package com.miracle.controller;

import com.google.common.util.concurrent.RateLimiter;
import com.miracle.entity.Stock;
import com.miracle.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.omg.CORBA.TIMEOUT;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.sql.Time;
import java.util.concurrent.TimeUnit;

/**
 * 秒杀
 * @author jie.xi
 * @date 2022年04月20日 10:11
 */

@RestController
@RequestMapping("stock")
@Slf4j
public class StockController {
    private RateLimiter rateLimiter = RateLimiter.create(40);
    @Autowired
    OrderService orderService;

    //开发秒杀，使用乐观锁
    @GetMapping("kill")
    public String kill(Integer id){
        System.out.println("秒杀商品的id:"+id);
        //根据秒杀商品id，调用秒杀业务
        try {
            int orderId = orderService.kill(id);
            return "秒杀成功，订单ID：" + String.valueOf(orderId);
        } catch (Exception e) {
            e.printStackTrace();
            return e.getMessage();
        }
    }

    /*
     * 乐观锁防止超卖+令牌桶防止超卖
     * @author jie.xi
     * @date 2022/4/20 16:26
     * @param id
     * @return java.lang.String
     */
    @GetMapping("killToken")
    public String killToken(Integer id){
        System.out.println("秒杀商品的id:"+id);
        //加入令牌桶的限流措施
        if(!rateLimiter.tryAcquire(5,TimeUnit.SECONDS)){
            log.info("请求抛球，抢购失败");
            return "抢购失败，活动过于火爆，请重试";
        }
        try {
            int orderId = orderService.kill(id);
            return "秒杀成功，订单ID：" + String.valueOf(orderId);
        } catch (Exception e) {
            e.printStackTrace();
            return e.getMessage();
        }
    }

    /*
     * 测试令牌桶
     * @author jie.xi
     * @date 2022/4/20 16:23
     * @param id
     * @return java.lang.String
     */
    @GetMapping("sale")
    public String sale(Integer id){
        //1.没有获取到token请求一直到获取到token令牌
        log.info("等待的时间："+rateLimiter.acquire());
        //2.设置一个等待时间，如果在等待时间内获取到了token令牌，则处理业务，如果在等待时间内没有获取到响应token则抛弃
        if(!rateLimiter.tryAcquire(2, TimeUnit.SECONDS)){
            System.out.println("当前请求被限流，直接抛弃，无法调用后续秒杀逻辑");
            return "抢购失败";
        }
        System.out.println("=============");
        return "抢购成功";

    }

    /*
     * 获取MD5
     * @author jie.xi
     * @date 2022/4/20 17:39
     * @param id
     * @param userid
     * @return java.lang.String
     */
    @RequestMapping("md5")
    public String getMd5(Integer id,Integer userid){
        String md5;
        try {
            md5 = orderService.getMd5(id,userid);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return "获取md5信息为："+md5;
    }


    @GetMapping("killTokenAndHide")
    public String killTokenAndHide(Integer id,Integer userid,String md5){
        //加入令牌桶的限流措施
        if(!rateLimiter.tryAcquire(5,TimeUnit.SECONDS)){
            log.info("请求抛球，抢购失败");
            return "抢购失败，活动过于火爆，请重试";
        }
        try {
            int orderId = orderService.kill(id,userid,md5);
            return "秒杀成功，订单ID：" + String.valueOf(orderId);
        } catch (Exception e) {
            e.printStackTrace();
            return e.getMessage();
        }
    }


}
